<?php

/**
 * Description of EventSubscriber
 *
 * @author nikolov
 */

namespace Shared\LRC\Event;

class EventSubscriber implements \Doctrine\Common\EventSubscriber {

	/**
	 *
	 * @var \Doctrine\ORM\EntityManager
	 */
	private $entityManager;

	public function getSubscribedEvents() {
		return array('postLoad');
	}

	/**
	 * 
	 * @param object$entity
	 * @param \Shared\Entity\Language $language
	 * @return string
	 */
	static public function getResultCacheId($entity, $language) {
		return sprintf('t-%s-%d-%d', \Shared\EntityUtils::getEntityFQCN($entity), $entity->getId(), $language->getId());
	}

	public function postLoad($Event) {
		$Em = $Event->getEntityManager();
		$this->entityManager = $Em;
		$Entity = $Event->getEntity();

		if ($Entity instanceof \Shared\LRC\Entity\TranslatableI) {

			$EntityParser = new \Shared\LRC\Metadata\Parsers\Entity($Entity, $Em);
			$EntityMetadata = $EntityParser->parse();

			$Language = \Shared\Application::instance()->getLRCSupport()->getCurrentLanguage();

			$TranslationParser = new \Shared\LRC\Metadata\Parsers\Translation($EntityMetadata->getTranslationEntityClass(), $Em);
			$TranslationMetadata = $TranslationParser->parse();

			$ObjectPropertyName = $TranslationMetadata->getObjectPropertyName();
			$LanguagePropertyName = $TranslationMetadata->getLanguagePropertyName();
			$Qb = $Em->createQueryBuilder();
			$Qb->select('lrc')->from($EntityMetadata->getTranslationEntityClass(), 'lrc')
					->where('lrc.' . $ObjectPropertyName . ' = :Object')
					->andWhere('lrc.' . $LanguagePropertyName . ' = :Language')
					->setParameter('Object', $Entity)
					->setParameter('Language', $Language)
					->setMaxResults(1);

			$Query = $Qb->getQuery();

			/* @var $Query \Doctrine\ORM\Query */


			if ($Query->getResultCacheDriver()) {
				$Query->useResultCache(true, 21600, $this->getResultCacheId($Entity, $Language));
			}

			$results = $Query->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);

			if ($results) {
				$translation = $results[0];
				foreach ($EntityMetadata->getLrcProperties() as $prop) {
					$value = $translation[$prop];
					$Entity->{'set' . ucfirst($prop)}($value);
				}
				if ($EntityMetadata->getLrcAssociations()) {
					$objectId = $translation['id'];
					$metadata = $this->entityManager->getClassMetadata($EntityMetadata->getTranslationEntityClass());
					foreach ($EntityMetadata->getLrcAssociations() as $prop) {
						$mapping = $metadata->associationMappings[$prop];
						$value = $this->entityManager->getRepository($mapping['targetEntity'])
								->findBy(array($mapping['mappedBy'] => $objectId));
						$Entity->{'set' . ucfirst($prop)}($value);
					}
				}
			}
		}
	}

}
